// Tierless
// Copyright © 2010 Alphora
// This file is licensed under a modified BSD-license (see tierless_license.txt).
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace Tierless.Framework.Data
{
	/// <summary>
	/// Specifies an entity type to be retrieved as part of an entity query.
	/// </summary>
	[DataContract]
	public class EntitySpecifier
	{
		/// <summary>
		/// Initializes a new instance of the EntitySpecifier class.
		/// </summary>
		/// <param name="entityTypeName">The name of the entity type.</param>
		/// <param name="commandName">The name of the command.</param>
		/// <param name="forUpdate">Whether or not the entities retrieved are intended for update.</param>
		/// <param name="relatedEntitySpecifiers">An optional list of related entity specifiers.</param>
		public EntitySpecifier(string entityTypeName, string commandName, bool forUpdate, List<RelatedEntitySpecifier> relatedEntitySpecifiers)
		{
			EntityTypeName = entityTypeName;
			_commandName = commandName;
			ForUpdate = forUpdate;
			_relatedEntitySpecifiers = relatedEntitySpecifiers;
		}

		/// <summary>
		/// Initializes a new instance of the EntitySpecifier class.
		/// </summary>
		/// <param name="entityTypeName">The name of the entity type.</param>
		/// <param name="commandName">The name of the command.</param>
		/// <param name="forUpdate">Whether or not the entities retrieved are intended for update.</param>
		/// <param name="relatedEntitySpecifiers">An optional list of related entity specifiers.</param>
		public EntitySpecifier(string entityTypeName, string commandName, bool forUpdate, params RelatedEntitySpecifier[] relatedEntitySpecifiers)
			: this(entityTypeName, commandName, forUpdate, new List<RelatedEntitySpecifier>(relatedEntitySpecifiers))
		{}

		/// <summary>
		/// Initializes a new instance of the EntitySpecifier class.
		/// </summary>
		/// <param name="entityTypeName">The name of the entity type.</param>
		/// <param name="commandName">The name of the command.</param>
		/// <param name="relatedEntitySpecifiers">An optional list of related entity specifiers.</param>
		public EntitySpecifier(string entityTypeName, string commandName, List<RelatedEntitySpecifier> relatedEntitySpecifiers)
			: this(entityTypeName, commandName, false, relatedEntitySpecifiers)
		{}

		/// <summary>
		/// Initializes a new instance of the EntitySpecifier class.
		/// </summary>
		/// <param name="entityTypeName">The name of the entity type.</param>
		/// <param name="commandName">The name of the command.</param>
		/// <param name="relatedEntitySpecifiers">An optional list of related entity specifiers.</param>
		public EntitySpecifier(string entityTypeName, string commandName, params RelatedEntitySpecifier[] relatedEntitySpecifiers)
			: this(entityTypeName, commandName, false, new List<RelatedEntitySpecifier>(relatedEntitySpecifiers))
		{}

		/// <summary>
		/// Initializes a new instance of the EntitySpecifier class.
		/// </summary>
		/// <param name="entityTypeName">The name of the entity type.</param>
		/// <param name="forUpdate">Whether or not the entities retrieved are intended for update.</param>
		/// <param name="relatedEntitySpecifiers">An optional list of related entity specifiers.</param>
		public EntitySpecifier(string entityTypeName, bool forUpdate, List<RelatedEntitySpecifier> relatedEntitySpecifiers)
			: this(entityTypeName, null, forUpdate, relatedEntitySpecifiers)
		{}

		/// <summary>
		/// Initializes a new instance of the EntitySpecifier class.
		/// </summary>
		/// <param name="entityTypeName">The name of the entity type.</param>
		/// <param name="forUpdate">Whether or not the entities retrieved are intended for update.</param>
		/// <param name="relatedEntitySpecifiers">An optional list of related entity specifiers.</param>
		public EntitySpecifier(string entityTypeName, bool forUpdate, params RelatedEntitySpecifier[] relatedEntitySpecifiers)
			: this(entityTypeName, null, forUpdate, relatedEntitySpecifiers)
		{}

		/// <summary>
		/// Initializes a new instance of the EntitySpecifier class.
		/// </summary>
		/// <param name="entityTypeName">The name of the entity type.</param>
		/// <param name="relatedEntitySpecifiers">An optional list of related entity specifiers.</param>
		public EntitySpecifier(string entityTypeName, List<RelatedEntitySpecifier> relatedEntitySpecifiers)
			: this(entityTypeName, null, false, relatedEntitySpecifiers)
		{}

		/// <summary>
		/// Initializes a new instance of the EntitySpecifier class.
		/// </summary>
		/// <param name="entityTypeName">The name of the entity type.</param>
		/// <param name="relatedEntitySpecifiers">An optional list of related entity specifiers.</param>
		public EntitySpecifier(string entityTypeName, params RelatedEntitySpecifier[] relatedEntitySpecifiers)
			: this(entityTypeName, null, false, relatedEntitySpecifiers)
		{}

		/// <summary>
		/// Gets the name of the entity type for the specifier.
		/// </summary>
		[DataMember]
		public string EntityTypeName { get; private set; }

		[DataMember]
		private string _commandName;

		/// <summary>
		/// Gets the name of the command for the specifier.
		/// </summary>
		public string CommandName
		{
			get { return _commandName; }
		}

		/// <summary>
		/// Gets whether or not the entities being retrieved are intended for updated.
		/// </summary>
		public bool ForUpdate { get; private set; }

		[DataMember]
		private List<RelatedEntitySpecifier> _relatedEntitySpecifiers;

		/// <summary>
		/// Gets the list of related entity specifiers.
		/// </summary>
		public List<RelatedEntitySpecifier> RelatedEntitySpecifiers
		{
			get { return _relatedEntitySpecifiers; }
		}

		/// <summary>
		/// Gets or sets an optional parent related entity specifier.
		/// </summary>
		public RelatedEntitySpecifier Parent { get; set; }
	}
}